"""简化的输入处理器"""
import threading
import time
import jieba
import re
import requests
import subprocess
from .config import GPIO_CONFIG, VOICE_CONFIG, setup_logging
from .battery_monitor import BatteryMonitor
from .rotary_controller import RotaryController

try:
    if GPIO_CONFIG.get('is_orangepi', False):
        import OPi.GPIO as GPIO
    else:
        class MockGPIO:
            BOARD = 'BOARD'
            IN = 'IN'
            OUT = 'OUT'
            PUD_UP = 'PUD_UP'
            HIGH = 1
            LOW = 0
            @staticmethod
            def setmode(mode): pass
            @staticmethod
            def setup(pin, mode, pull_up_down=None): pass
            @staticmethod
            def input(pin): return 1
            @staticmethod
            def output(pin, value): pass
            @staticmethod
            def cleanup(): pass
        GPIO = MockGPIO()
except Exception:
    class MockGPIO:
        BOARD = 'BOARD'
        IN = 'IN'
        OUT = 'OUT'
        PUD_UP = 'PUD_UP'
        HIGH = 1
        LOW = 0
        @staticmethod
        def setmode(mode): pass
        @staticmethod
        def setup(pin, mode, pull_up_down=None): pass
        @staticmethod
        def input(pin): return 1
        @staticmethod
        def output(pin, value): pass
        @staticmethod
        def cleanup(): pass
    GPIO = MockGPIO()

try:
    from listen import XunfeiIatRecognizer
except ImportError:
    # 当语音识别不可用时的占位符
    class XunfeiIatRecognizer:
        def __init__(self, appid, api_key, api_secret):
            from .config import setup_logging
            self.logger = setup_logging('MockXunfeiIAT')
            # 使用模拟语音识别器
        
        def start_recognition(self, callback):
            # 不提供模拟结果，直接报错
            self.logger.error("语音识别不可用 - 需要配置真实的语音识别服务")
            if callback:
                callback(None)  # 返回None表示识别失败
        
        def stop_recognition(self):
            pass

class InputHandler:
    """统一的输入处理器"""
    
    def __init__(self, message_processor, error_handler=None, data_processor=None):
        self.message_proc = message_processor
        self.error_handler = error_handler
        self.data_processor = data_processor
        self.logger = setup_logging('Input')
        
        # 语音识别
        self.recognizer = XunfeiIatRecognizer(
            VOICE_CONFIG['xunfei_appid'],
            VOICE_CONFIG['xunfei_api_key'],
            VOICE_CONFIG['xunfei_api_secret']
        )
        
        # 状态控制
        self.running = False
        self.listening = False
        self.monitor_thread = None
        self.recognition_thread = None
        
        # 按钮状态管理
        self.button_mode = 'idle'  # 'idle', 'short_pressed', 'continuous_listening', 'press_to_talk'
        self.last_short_press_time = 0
        self.short_press_timeout = 2.0  # 短按后等待长按的超时时间
        
        # 语音识别结果缓存（用于延迟处理）
        self.pending_recognition_result = None
        self._was_continuous_mode = False  # 标记是否为持续录音模式
        
        # TTS播报控制
        self.current_tts_thread = None
        self.tts_stop_event = threading.Event()
        
        # 高德地图API配置
        self.amap_api_key = "your_amap_api_key_here"  # 需要配置实际的API密钥
        self.geocode_url = "https://restapi.amap.com/v3/geocode/geo"
        self.walking_url = "https://restapi.amap.com/v5/direction/walking"
        
        # 初始化jieba分词
        jieba.initialize()
        
        # 地点关键词
        self.location_keywords = ['到', '去', '从', '出发', '目的地', '终点', '起点']
        
        # 初始化TTS引擎
        self._init_tts()
        
        # 初始化电量监控器
        self.battery_monitor = BatteryMonitor(tts_callback=self._speak_text)
        
        # 初始化旋钮控制器
        self.rotary_controller = RotaryController(
            tts_callback=self._speak_text,
            shutdown_callback=self._handle_system_shutdown
        )
        
        # GPIO初始化
        self._gpio_ok = False
        self._init_gpio()
    
    def text_to_speech_espeak(self, text, lang='zh'):
        """使用espeak进行语音合成"""
        try:
            # 转义特殊字符
            text = text.replace('"', '\\"').replace("'", "\\'")
            cmd = f'espeak -v {lang} "{text}"'
            subprocess.call(cmd, shell=True)
        except Exception as e:
            self.logger.error(f"espeak TTS失败: {e}")
    
    def _init_tts(self):
        """初始化TTS引擎 - 使用espeak"""
        try:
            self.logger.info("初始化espeak TTS引擎...")
            
            # 测试espeak是否可用
            result = subprocess.run(['espeak', '--version'], 
                                  capture_output=True, text=True, timeout=5)
            
            if result.returncode == 0:
                self.logger.info("✅ espeak TTS引擎初始化成功")
                self.tts_engine = True  # 标记TTS可用
            else:
                raise Exception("espeak命令不可用")
                
        except subprocess.TimeoutExpired:
            self.logger.error("espeak命令超时")
            self.tts_engine = False
        except FileNotFoundError:
            self.logger.error("espeak未安装，请安装espeak: sudo apt-get install espeak")
            self.tts_engine = False
        except Exception as e:
            self.logger.error(f"espeak TTS初始化失败: {e}")
            self.tts_engine = False
    
    def _init_gpio(self):
        """初始化GPIO"""
        try:
            if GPIO_CONFIG.get('is_orangepi', False):
                GPIO.setmode(GPIO.BOARD)
                try:
                    GPIO.setwarnings(False)
                except Exception:
                    pass
                GPIO.setup(GPIO_CONFIG['button_pin'], GPIO.IN, pull_up_down=GPIO.PUD_UP)
                GPIO.setup(GPIO_CONFIG['led_pin'], GPIO.OUT)
                GPIO.output(GPIO_CONFIG['led_pin'], GPIO.LOW)
                self.logger.info(f"GPIO初始化成功 - 按钮引脚: {GPIO_CONFIG['button_pin']}, LED引脚: {GPIO_CONFIG['led_pin']}")
                self._gpio_ok = True
            else:
                self.logger.info("开发环境模式，使用模拟GPIO")
                self._gpio_ok = True
        except Exception as e:
            self.logger.error(f"GPIO初始化失败: {e}")
            if self.error_handler:
                self.error_handler.log_error("GPIOInit", f"GPIO初始化失败: {e}", "InputHandler")
            self._gpio_ok = False

    def _safe_gpio_input(self, pin):
        try:
            return GPIO.input(pin)
        except Exception as e:
            if self._gpio_ok:
                self.logger.error(f"GPIO输入错误(pin={pin}): {e}")
            return GPIO.HIGH

    def _safe_gpio_output(self, pin, value):
        try:
            GPIO.output(pin, value)
        except Exception as e:
            if self._gpio_ok:
                self.logger.error(f"GPIO输出错误(pin={pin}): {e}")
    
    def start(self):
        """启动输入监控"""
        if self.running:
            return
        
        self.running = True
        self.monitor_thread = threading.Thread(target=self._monitor_loop)
        self.monitor_thread.daemon = True
        self.monitor_thread.start()
        
        # 启动电量监控
        self.battery_monitor.start_monitoring()
        
        # 启动旋钮控制器
        self.rotary_controller.start()
        
        # 延迟播报开机电量状态（等待TTS初始化完成）
        def delayed_battery_announcement():
            time.sleep(3)  # 等待3秒确保系统完全启动
            self.battery_monitor.announce_battery_status()
        
        battery_thread = threading.Thread(target=delayed_battery_announcement)
        battery_thread.daemon = True
        battery_thread.start()
    
    def stop(self):
        """停止输入监控"""
        self.running = False
        self.stop_listening()
        
        # 停止当前的语音播报
        self._stop_current_speech()
        
        # 停止电量监控
        if hasattr(self, 'battery_monitor'):
            self.battery_monitor.stop_monitoring()
        
        # 停止旋钮控制器
        if hasattr(self, 'rotary_controller'):
            self.rotary_controller.stop()
        
        if self.monitor_thread:
            self.monitor_thread.join(timeout=2)
        
        try:
            GPIO.cleanup()
            self.logger.info("GPIO资源已清理")
        except Exception as e:
            self.logger.error(f"GPIO清理失败: {e}")
        
        self.logger.info("输入处理器已停止")
    
    def _monitor_loop(self):
        """监控循环"""
        button_pressed = False
        press_start_time = 0
        
        while self.running:
            try:
                current_time = time.time()
                # 检查按钮状态（修正逻辑反转问题）
                current_button_state = self._safe_gpio_input(GPIO_CONFIG['button_pin']) == GPIO.HIGH
                
                # 检查短按超时
                if self.button_mode == 'short_pressed' and current_time - self.last_short_press_time > self.short_press_timeout:
                    self.button_mode = 'idle'
                    self.logger.info("短按超时，返回空闲状态")
                
                if current_button_state and not button_pressed:
                    # 按钮刚被按下
                    button_pressed = True
                    press_start_time = current_time
                    self.logger.info("按钮按下")
                    
                elif not current_button_state and button_pressed:
                    # 按钮刚被释放
                    button_pressed = False
                    press_duration = current_time - press_start_time
                    
                    self.logger.info(f"按钮释放，持续时间: {press_duration:.2f}秒")
                    
                    if self.button_mode == 'press_to_talk':
                        # 按压录音模式中松开：结束录音
                        self.stop_listening()
                        self.button_mode = 'idle'
                        self.logger.info("按压录音结束")
                    elif self.button_mode == 'continuous_listening':
                        # 持续录音模式中松开：结束录音并处理语音
                        self._was_continuous_mode = True  # 标记为持续录音模式
                        self.stop_listening()
                        # 等待一小段时间确保语音识别完成
                        time.sleep(0.5)
                        # 处理缓存的语音识别结果
                        if self.pending_recognition_result:
                            self.logger.info("松手后开始处理语音识别结果")
                            self._process_recognition_result(self.pending_recognition_result)
                            self.pending_recognition_result = None
                        else:
                            self.logger.warning("松手时没有待处理的语音识别结果")
                        self._was_continuous_mode = False
                        self.button_mode = 'idle'
                        self.logger.info("持续录音结束，语音处理完成")
                    elif press_duration < 1.0:
                        # 短按处理
                        self._handle_short_press()
                    elif press_duration >= 1.0 and self.button_mode == 'short_pressed':
                        # 短按后长按：启动持续录音模式
                        self.button_mode = 'continuous_listening'
                        self.start_listening()
                        self.logger.info("启动持续录音模式")
                    elif press_duration >= 3.0:
                        # 超长按：发送硬件就绪消息
                        self.logger.info("超长按检测到，发送硬件就绪消息")
                        self.message_proc.send_text_message("硬件就绪")
                
                # 检查是否正在长按（用于按压录音模式）
                elif button_pressed and self.button_mode == 'idle':
                    press_duration = current_time - press_start_time
                    if press_duration >= 1.0 and not self.listening:
                        # 直接长按模式：开始按压录音
                        self.button_mode = 'press_to_talk'
                        self.start_listening()
                        self.logger.info("进入按压录音模式")
                
                time.sleep(0.1)  # 短暂休眠
                
            except Exception as e:
                self.logger.error(f"监控循环错误: {e}")
                time.sleep(1)
    
    def _handle_short_press(self):
        """处理短按"""
        if self.button_mode == 'idle':
            # 第一次短按：进入等待长按状态
            self.button_mode = 'short_pressed'
            self.last_short_press_time = time.time()
            self.logger.info("短按检测到，等待长按启动持续录音模式")
        elif self.button_mode == 'short_pressed':
            # 短按后再次短按：取消等待
            self.button_mode = 'idle'
            self.logger.info("取消等待长按")
    
    def _handle_long_press(self, press_duration):
        """处理长按（备用函数，主要逻辑已在监控循环中处理）"""
        # 这个函数现在主要作为备用，大部分长按逻辑已经在监控循环中处理
        pass
    
    def start_listening(self):
        """开始语音识别"""
        if self.listening:
            self.logger.warning("语音识别已在运行")
            return
        
        # 开始新的语音输入时，打断当前播报
        self._stop_current_speech()
        
        self.listening = True
        self._safe_gpio_output(GPIO_CONFIG['led_pin'], GPIO.HIGH)  # 点亮LED
        
        self.recognition_thread = threading.Thread(target=self._recognition_loop)
        self.recognition_thread.daemon = True
        self.recognition_thread.start()
        
        self.logger.info("语音识别已启动")
    
    def stop_listening(self):
        """停止语音识别"""
        if not self.listening:
            return
        
        self.listening = False
        self._safe_gpio_output(GPIO_CONFIG['led_pin'], GPIO.LOW)  # 熄灭LED
        
        try:
            self.recognizer.stop_recognition()
        except Exception as e:
            self.logger.error(f"停止语音识别失败: {e}")
        
        if self.recognition_thread:
            self.recognition_thread.join(timeout=2)
        
        self.logger.info("语音识别已停止")
    
    def _speak_text(self, text):
        """语音播报文本（使用espeak）"""
        if not self.tts_engine:
            self.logger.warning("TTS引擎未初始化，无法播报语音")
            return
        
        try:
            # 先打断当前播报
            self._stop_current_speech()
            
            self.logger.info(f"开始语音播报: {text[:50]}...")
            
            # 重置停止事件
            self.tts_stop_event.clear()
            
            # 在新线程中播报，避免阻塞主线程
            def speak_in_thread():
                try:
                    # 检查是否需要停止
                    if self.tts_stop_event.is_set():
                        return
                    
                    # 使用espeak进行语音合成
                    self.text_to_speech_espeak(text)
                        
                except Exception as e:
                    self.logger.error(f"TTS播报线程错误: {e}")
                finally:
                    # 播报完成后清理当前线程引用
                    if self.current_tts_thread == threading.current_thread():
                        self.current_tts_thread = None
            
            self.current_tts_thread = threading.Thread(target=speak_in_thread)
            self.current_tts_thread.daemon = True
            self.current_tts_thread.start()
            
        except Exception as e:
            self.logger.error(f"语音播报失败: {e}")
    
    def _stop_current_speech(self):
        """停止当前的语音播报"""
        try:
            if self.current_tts_thread and self.current_tts_thread.is_alive():
                self.logger.info("打断当前语音播报")
                # 设置停止事件
                self.tts_stop_event.set()
                # 对于espeak，我们可以尝试终止进程
                try:
                    subprocess.run(['pkill', 'espeak'], timeout=1)
                except:
                    pass
                # 等待线程结束（最多等待0.5秒）
                self.current_tts_thread.join(timeout=0.5)
                self.current_tts_thread = None
        except Exception as e:
            self.logger.error(f"停止语音播报失败: {e}")
    
    def _recognition_loop(self):
        """语音识别循环"""
        try:
            self.recognizer.start_recognition(self._on_recognition_result)
        except Exception as e:
            self.logger.error(f"语音识别错误: {e}")
            self.listening = False
            GPIO.output(GPIO_CONFIG['led_pin'], GPIO.LOW)
    
    def _on_recognition_result(self, result):
        """语音识别结果回调"""
        if result is None:
            self.logger.error("语音识别失败，无法获取识别结果")
            self.pending_recognition_result = None
        elif result and result.strip():
            self.logger.info(f"识别结果: {result}")
            # 缓存识别结果，等待松手后处理
            self.pending_recognition_result = result
        else:
            self.logger.warning("语音识别结果为空")
            self.pending_recognition_result = None
        
        # 根据模式决定是否停止监听
        if self.button_mode == 'press_to_talk':
            # 按压录音模式：立即处理并停止监听
            if self.pending_recognition_result:
                self._process_recognition_result(self.pending_recognition_result)
            self.stop_listening()
            self.button_mode = 'idle'
            self.pending_recognition_result = None
        elif self.button_mode == 'continuous_listening':
            # 持续录音模式：不自动停止，等待用户松手后处理
            self.logger.info("持续录音模式：等待松手后处理语音")
        else:
            # 其他模式：立即处理并停止监听
            if self.pending_recognition_result:
                self._process_recognition_result(self.pending_recognition_result)
            self.stop_listening()
            self.pending_recognition_result = None
    
    def _process_recognition_result(self, result):
        """处理语音识别结果"""
        self.logger.info(f"开始处理语音识别结果: {result}")
        
        # 判断是否为路线指令
        if self._is_route_command(result):
            if self._was_continuous_mode:
                # 持续录音模式：执行智能路线规划
                self.logger.info("使用智能路线规划处理语音指令")
                self._handle_intelligent_navigation(result)
            else:
                # 其他模式：使用原有的简单路线处理
                self.logger.info("使用简单路线处理语音指令")
                start, end = self._parse_route_command(result)
                self.message_proc.send_route_message(start, end)
        else:
            # 发送文本消息
            self.logger.info("发送文本消息")
            self.message_proc.send_text_message(result)
    
    def _is_route_command(self, text):
        """判断是否为路线指令"""
        route_keywords = ['到', '去', '从', '导航', '路线', '怎么走']
        return any(keyword in text for keyword in route_keywords)
    
    def _parse_route_command_with_jieba(self, text):
        """使用jieba分词解析路线指令，提取起点和终点"""
        try:
            # 使用jieba分词
            words = list(jieba.cut(text))
            self.logger.info(f"分词结果: {words}")
            
            # 查找地点信息
            origin = None
            destination = None
            
            # 分析语句结构
            text_lower = text.lower()
            
            # 模式1: "从A到B" 或 "从A去B"
            if '从' in text and ('到' in text or '去' in text):
                from_match = re.search(r'从([^到去]+)(?:到|去)(.+)', text)
                if from_match:
                    origin = from_match.group(1).strip()
                    destination = from_match.group(2).strip()
            
            # 模式2: "到A" 或 "去A" (没有起点)
            elif '到' in text or '去' in text:
                to_match = re.search(r'(?:到|去)(.+)', text)
                if to_match:
                    destination = to_match.group(1).strip()
            
            # 清理地点名称
            if origin:
                origin = self._clean_location_name(origin)
            if destination:
                destination = self._clean_location_name(destination)
            
            self.logger.info(f"解析结果 - 起点: {origin}, 终点: {destination}")
            return origin, destination
            
        except Exception as e:
            self.logger.error(f"路线指令解析失败: {e}")
            return None, None
    
    def _clean_location_name(self, location):
        """清理地点名称，移除无关词汇"""
        if not location:
            return None
        
        # 移除常见的无关词汇
        stop_words = ['的', '了', '吧', '呢', '啊', '哦', '嗯', '那', '这', '个']
        for word in stop_words:
            location = location.replace(word, '')
        
        return location.strip()
    
    def _get_current_location(self):
        """获取当前GPS位置"""
        try:
            if self.data_processor:
                location_data = self.data_processor.generate_location_data()
                if location_data and 'coordinates' in location_data:
                    lat = location_data['coordinates']['latitude']
                    lng = location_data['coordinates']['longitude']
                    return f"{lng},{lat}"  # 高德API格式：经度,纬度
            
            # 如果GPS不可用，返回默认位置（北京天安门）
            self.logger.warning("GPS不可用，使用默认位置")
            return "116.397428,39.90923"
            
        except Exception as e:
            self.logger.error(f"获取当前位置失败: {e}")
            return "116.397428,39.90923"  # 默认位置
    
    def _geocode_address(self, address):
        """将地址转换为经纬度坐标"""
        try:
            params = {
                'key': self.amap_api_key,
                'address': address
            }
            
            response = requests.get(self.geocode_url, params=params, timeout=10)
            result = response.json()
            
            if result['status'] == '1' and result['count'] != '0':
                location = result['geocodes'][0]['location']
                self.logger.info(f"地址 '{address}' 转换为坐标: {location}")
                return location
            else:
                self.logger.error(f"地址转换失败: {result}")
                return None
                
        except Exception as e:
            self.logger.error(f"地址转换异常: {e}")
            return None
    
    def _get_walking_navigation(self, origin, destination):
        """获取步行导航路线"""
        try:
            params = {
                'key': self.amap_api_key,
                'origin': origin,
                'destination': destination,
                'show_fields': 'cost,navi,polyline'
            }
            
            response = requests.get(self.walking_url, params=params, timeout=10)
            result = response.json()
            
            if result['status'] == '1':
                self.logger.info("路线规划成功")
                return result
            else:
                self.logger.error(f"路线规划失败: {result}")
                return None
                
        except Exception as e:
            self.logger.error(f"路线规划异常: {e}")
            return None
    
    def _process_navigation_result(self, nav_result):
        """处理导航结果，生成适合盲人用户的详细语音播报内容"""
        try:
            if not nav_result or 'route' not in nav_result:
                return "无法获取路线信息"
            
            route = nav_result['route']
            paths = route['paths'][0]  # 取第一条路径
            
            # 基本信息
            distance = int(paths['distance']) / 1000  # 转换为公里
            duration = int(paths['cost']['duration']) / 60 if 'cost' in paths else 0  # 转换为分钟
            
            # 构建适合语音播报的路线摘要
            summary = f"路线规划完成。总距离{distance:.1f}公里，预计步行时间{duration:.0f}分钟。\n\n"
            
            # 获取详细导航步骤，为盲人用户提供更多细节
            steps = paths['steps']
            summary += "详细路线指引如下：\n"
            
            for i, step in enumerate(steps, 1):
                instruction = step['instruction']
                road_name = step.get('road_name', '')
                step_distance = int(step['step_distance'])
                
                # 构建更详细的语音指引
                step_text = f"第{i}步："
                
                if step_distance > 0:
                    if step_distance >= 1000:
                        distance_text = f"{step_distance/1000:.1f}公里"
                    else:
                        distance_text = f"{step_distance}米"
                    step_text += f"{instruction}，距离{distance_text}"
                else:
                    step_text += instruction
                
                if road_name and road_name != '未命名道路':
                    step_text += f"，沿{road_name}前行"
                
                summary += step_text + "。\n"
                
                # 为了语音播报效果，限制步骤数量
                if i >= 8:  # 最多播报8步
                    remaining_steps = len(steps) - i
                    if remaining_steps > 0:
                        summary += f"后续还有{remaining_steps}个导航步骤，请注意导航提示。\n"
                    break
            
            summary += "\n请注意安全，祝您一路顺风。"
            
            return summary
            
        except Exception as e:
            self.logger.error(f"处理导航结果失败: {e}")
            return "路线信息处理失败"
    
    def _parse_route_command(self, text):
        """解析路线指令（保持兼容性）"""
        return self._parse_route_command_with_jieba(text)
    
    def _handle_intelligent_navigation(self, text):
        """处理智能导航请求"""
        try:
            self.logger.info(f"开始智能路线规划: {text}")
            
            # 1. 使用jieba分词解析起点和终点
            origin_name, destination_name = self._parse_route_command_with_jieba(text)
            
            if not destination_name:
                self.message_proc.send_text_message("无法识别目的地，请重新说明")
                return
            
            # 2. 获取起点坐标
            if origin_name:
                # 用户指定了起点，进行地址转换
                origin_coords = self._geocode_address(origin_name)
                if not origin_coords:
                    self.message_proc.send_text_message(f"无法找到起点位置: {origin_name}")
                    return
            else:
                # 用户未指定起点，使用GPS坐标
                origin_coords = self._get_current_location()
                origin_name = "当前位置"
            
            # 3. 获取终点坐标
            destination_coords = self._geocode_address(destination_name)
            if not destination_coords:
                self.message_proc.send_text_message(f"无法找到目的地位置: {destination_name}")
                return
            
            # 4. 调用高德API获取路线
            nav_result = self._get_walking_navigation(origin_coords, destination_coords)
            if not nav_result:
                self.message_proc.send_text_message("路线规划失败，请稍后重试")
                return
            
            # 5. 处理导航结果并发送
            route_summary = self._process_navigation_result(nav_result)
            navigation_message = f"从{origin_name}到{destination_name}的{route_summary}"
            
            self.logger.info("智能路线规划成功")
            
            # 发送文本消息
            self.message_proc.send_text_message(navigation_message)
            
            # 语音播报导航信息
            self._speak_text(navigation_message)
            
            # 6. 同时发送原始路线消息（保持兼容性）
            self.message_proc.send_route_message(origin_name, destination_name)
            
        except Exception as e:
            self.logger.error(f"智能导航处理失败: {e}")
            self.message_proc.send_text_message("导航服务暂时不可用，请稍后重试")
    
    def _handle_system_shutdown(self):
        """处理系统关机"""
        try:
            self.logger.warning("收到关机信号，开始关闭系统")
            
            # 停止所有服务
            self.stop()
            
            # 通知其他组件系统即将关机
            if self.message_proc:
                self.message_proc.send_text_message("系统关机中...")
            
            self.logger.info("系统关机处理完成")
            
        except Exception as e:
            self.logger.error(f"系统关机处理失败: {e}")
    
    def get_volume(self):
        """获取当前音量"""
        if hasattr(self, 'rotary_controller'):
            return self.rotary_controller.get_current_volume()
        return 50
    
    def set_volume(self, volume):
        """设置音量"""
        if hasattr(self, 'rotary_controller'):
            self.rotary_controller.set_volume(volume)